
#ifndef LIST_T_H
#define LIST_T_H

/**
 * @file
 * List_t interface, with opaque object design pattern.
 */


/* Forward declaration. */
struct List_t;

/** @brief Convenience typedef. */
typedef struct List_t List_t;


/**
 * @name Constructor and destructor.
 * @{
 */

/**
 * @brief Constructor.
 *
 * @param Optional. Callback for deleting stored element during list destruction.
 */
List_t * list_new( void ( * elementDestructor)( void * ) );

/**
 * @brief Destructor.
 *
 * @param thisList The list to be destructed.
 */
void list_delete( List_t * thisList );

/*@}*/

/**
 * @name Queries.
 *@{
 */

/**
 * Returns 0 if the list is not empty.
 *
 * @param thisList The list.
 * @return A boolean indicating if the list is empty.
 */
int list_isEmpty( List_t * thisList );


/**
 * Returns the list length.
 *
 * @param thisList The list.
 * @return The list size.
 */
unsigned long int list_getSize( List_t * thisList );



/*@}*/

/**
 * @name Interface methods.
 *@{
 */

/**
 * @brief Adds an element as tail.
 *
 * @param thisList The list.
 * @param element The element to be added.
 * @return The element itself, or NULL on failure.
 */
void * list_addTail( List_t * thisList, void * element );

/**
 * @brief Gets the head.
 *
 * @param thisList The list.
 * @return The head, or NULL if there was no head.
 */
void * list_getHead( List_t * thisList );

/**
 * @brief Removes the head, whithout deleting the element.
 *
 * @param thisList The list.
 */
void list_removeHead( List_t * thisList );

/**
 * @brief Removes the head, deleting the element.
 *
 * @param thisList The list.
 */
void list_removeAndDeleteHead( List_t * thisList );


/* @TODO Add complementary get/set/remove methods.
 * @TODO Add accessors to any positions.
 * @TODO Add a method to set/unset the elementDestructor
 *       (i.e. the ownership of stored elements).
 * @TODO Add "copy constructor" which duplicates a list passed as argument.
 *       The "copy constructor" will take also a function pointer, to be called
 *       on each stored element to duplicate it.
 */

/* Extras:
 * @TODO Add iterators.
 * @TODO Add an "assignment" method by adding a cloning callback
 *       as constructor parameter. The new method will destroy the current list,
 *       and then will re-create the list as a copy of the second argument list and
 *       of its elements.
 */

/*@}*/




#endif
